package main

import (
	"fmt"
	"math/rand"
	"sort"
	"time"
)
func main() {
	/*    第一题
	s1 := make([]int,3,4)
	s2 := append(s1,1)
	请问s1 s2 内各有什么元素？
		答： s1 内的元素为: [ 0 0 0 ] len为3 cap 为4
		    s2 内的元素为: [ 0 0 0 1 ] len为4 cap为4
	s1 修改一个元素会影响s2嘛，s2修改一个元素会影响s1嘛？
		答： s1修改一个元素是对s2有影响的，因为 s1 s2虽然是两个切片(s1,s2内存地址不一样)，
			但是底层是使用的同一个数组,s1 和 s2 有一个共同特点 看到的切片的前三个元素都是一样的
			所以s1修改元素的话，s2也是会改变的。
			s2修改元素分两种情况
				1. 如果s2像s1那样修改的话，只修改前三个元素中的某一个，那么s1的切片也是有变化的，
					因为他们底层都是用的同一个数组，所以s2修改,s1也会跟着修改
				2. 如果s2修改第四个元素，那么对于s1来说他是看不到的，因为对于s1来说他的len为3，
					他只能看到前三个元素，第四个元素修改了他是看不到的,所以这种情况的话是对s1没有影响的
	s2 再增加一个元素会怎么样？
		答： 由第一问得知s2目前为 [ 0 0 0 1] len为4 cap为4 是基于s1得到的
			所以说如果这个时候s2再append的话，就会造成底层数组无法满足现在的需求,就会爆
			就会生成一个新的数组将原有的值copy到新数组，会给s2重新分配内存地址，重新分配后的s2
			len为5 cap为8, 此时的s2 和 s1 没有任何关系
	*/

	/* 第二题 有一个数组[1,4,9,16,2,5,10,15] 生成一个新切片， 要求新切片元素是数组相邻2项的和  */
	s1 := [...]int{1, 4, 9, 16, 2, 5, 10, 15}
	s2 := s1[:]
	for i, v := range s2 {
		if i < len(s2)-1{
			fmt.Printf("索引为:%d 结果为: %d \n", i, v+s2[i+1])
		}
	}
		/*
		索引为:0 结果为: 5 
		索引为:1 结果为: 13 
		索引为:2 结果为: 25 
		索引为:3 结果为: 18 
		索引为:4 结果为: 7 
		索引为:5 结果为: 15 
		索引为:6 结果为: 25 
		*/
	
		/* 第三题 随机生成一百个整数 从负一百到一百之间 然后降序排列，统计出 每一个数字出现的次数 */
		/* 解题思路 用切片存放数字并排序 ，用map存放 数字和出现的次数*/
		s5 := make([]int, 0, 100)
		r := rand.New(rand.NewSource(time.Now().UnixNano()))

		for i := 0; i < 100; i++ {
			s5 = append(s5, (r.Intn(201) - 100))
		}
		//fmt.Println( s1)
		sort.Sort(sort.Reverse(sort.IntSlice(s5)))
		fmt.Println( s1, len(s5), cap(s5))

		counts := make(map[int]int)

		for _, num := range s5 {
			counts[num]++
		}
		//fmt.Println(counts)
		for num, count := range counts {
			fmt.Printf("%d 出现了 %d 次\n", num, count)
		}



		/* 第四题 线性数据结构 和 hash表 */
		/* 
		线性数据结构有两种，一种是 顺序表一种是链接表，
			顺序表 链接表 都是有序序列， 对他们两个如何选型，其实就是看自己实际应用的时候对增删改查的使用频繁度来决定的
			如果经常在头部来增加或者删除，那么顺序表肯定是不合适的，因为每一次操作都会伴随着整个表统一向前或者向后移动代价很大。
			如果经常在中间 增删 顺序表也不合适，因为从删除的那个元素向后所有的元素，都会整体迁移
			如果增删都在尾部， 那么 顺序表和链接表都比较合适
		hash表 是非线形结构，是无序的
			它非常适合存放无须的kv数据对，存取的时候只需要对key进行读写，key不能重复，重复即覆盖。是有一个固定算法
			y = hash(x) ，很有可能不同的x得到一个共同的y值，这个时候就要做判断是怎么去存储，在go中一般使用的是拉链法，就是
			同一个底层地址，用链表尾部追加一个元素 ，存放两个元素，因为他们的key值不一样，总的来说影响不是很大，只要算法合理，那么这种概率就会变得很小
		*/


}
// 批改意见
// 1. 第三题在输出它统计次数的同时，尝试降序输出